/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *	  http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.googlecode.milib.actionControll {
	import com.googlecode.milib.base.MLActionClass;
	import com.googlecode.milib.util.MLArrayUtil;
	import com.googlecode.milib.vo.MLEvent;	

	/**
	 * For info see:
	 * [en] http://milib.info/index.php?view=article&catid=2%3Aclasses&id=13%3Aclass-queuedactions&option=com_content&Itemid=11
	 * [pl] http://milib.info/pl/index.php?view=article&catid=35%3Aklasy&id=59%3Aklasa-queuedactions&option=com_content&Itemid=63
	 * 
	 * @author Marek Brun
	 */
	public class QueuedActions extends MLActionClass {
		
		//data: MLActionClass
		public var event_RunnerFinish:String='RunnerFinish';
		//data: MLActionClass		public var event_RunnerStart:String='RunnerStart';
		
		private var actions : Array;
		public var name : String;
		private var currentAction:MLActionClass;
		private var finishedActions : Array;
		private var isRestoreAfterFinish : Boolean;
		private var actionInStart : Array;		public var isAutoStart : Boolean;
		private var currentStartingAction:MLActionClass;

		public function QueuedActions(actions:Array=null, isRestoreAfterFinish:Boolean=false, isAutoStart:Boolean=false) {
			this.actions=actions ? actions : [];
			this.isRestoreAfterFinish=isRestoreAfterFinish;
			this.isAutoStart=isAutoStart;
		}
		
		public function getGotAction(action:MLActionClass):Boolean {
			return MLArrayUtil.got(actions, action);
		}
		
		public function getCurrentAction():MLActionClass {
			return currentAction;
		}
		
		public function getCurrentStartingAction():MLActionClass {
			return currentStartingAction;
		}
		
		public function addActionToQueue(action:MLActionClass):void {
			if(MLArrayUtil.got(actions, action)){ return; }
			actions.push(action);
			if(isAutoStart){ start(); }
		}
		
		public function addActionsToQueue(actions:Array/*of MLActionClass*/):void {
			var i:uint;
			var loop:MLActionClass;
			for(i=0;i<actions.length;i++){
				loop=actions[i];
				addActionToQueue(loop);
			}
		}
		
		override protected function doStart():Boolean {
			if(!actions.length){ throw new Error('thre\'s no action to start; actions>'+dbg.link(actions)); return false; }
			if(isRestoreAfterFinish){ actionInStart=actions.concat(); }
			finishedActions=[];
			tryStartNextAction();
			return true;
		}
		
		override protected function doFinish():Boolean {
			if(currentAction.getIsRunning()){
				currentAction.finish();
				return true;
			}else{
				if(isRestoreAfterFinish){
					actions=actionInStart;
					actionInStart=null;
				}
				return true;
			}
			return false;
		}
		
		private function tryStartNextAction():void {
			if(actions.length && isRunningFlag){
				currentAction=MLActionClass(actions.shift());
				currentAction.addEventListener(currentAction.event_ActionFinish, onCurrentAction_ActionFinish);
				currentStartingAction=currentAction;
				broadcastEvent(event_RunnerStart, currentAction);
				currentAction.start();
				currentStartingAction=null;
			}else{
				finish();
			}
		}
		
		public function getFinishedActions():Array /*new array of MLActionClass*/ {
			return finishedActions.concat();
		}
		
		public function getUnstartedActions():Array /*new array of MLActionClass*/ {
			return actions.concat();
		}
		
//****************************************************************************
// EVENTS for runnersQueue
//****************************************************************************
		protected function onCurrentAction_ActionFinish(event:MLEvent):void {
			currentAction.removeEventListener(currentAction.event_ActionFinish, onCurrentAction_ActionFinish);
			broadcastEvent(event_RunnerFinish, currentAction);
			if(getIsRunningFlag()){
				finishedActions.push(currentAction);
				tryStartNextAction();
			}else{
				finish();
			}
		}
	
	}
}
